#include "manager.h"
#include "AReVi/arObject.h"
#include "AReVi/arSystem.h"
#include "AReVi/Lib3D/viewer3D.h"
#include "AReVi/Lib3D/simpleInteractor.h"
#include "AReVi/Utils/abstractStream.h"

#include "environment.h"
#include "element3D.h"
#include "event.h"

using namespace AReVi;

AR_CLASS_NOVOID_DEF(Manager, ArObject)

ArRef<Manager> Manager::_uniqueInstance = Manager::nullRef();

Manager::Manager(ArCW & arCW, ArRef<Connector> connector) : 
ArObject(arCW),
_connector(connector),
_renderer(Viewer3D::NEW()),
_interactor(SimpleInteractor::NEW())
{
    // On assigne _uniqueInstace
    _uniqueInstance = thisRef();
    
    // On créé l'environnement partagé entre les clients
    _environment = Environment::NEW();

    // Initialisation du renderer
    unsigned int w,h;
    Renderer3D::getScreenSize(w,h);
    ar_down_cast<Viewer3D>(_renderer)->setWindowGeometry(0,0,w/2,h/2);
    ar_down_cast<Viewer3D>(_renderer)->setMapped(true);
    _renderer->setFarDistance(50000.0);
    _interactor->setRenderer(_renderer);

    // Gestion de la fermeture du renderer
    _renderer->setCloseAction(Renderer3D::CLOSE_LEAVE);
    _renderer->addCloseCB(thisRef(), &Manager::_onClose);
}

Manager::~Manager() {
}


void Manager::createManager(ArRef<Connector> connector) {
    Manager::NEW(connector);
    
    //Retreive elements from other managers!
    ArRef<Event> evt = Event::NEW();
    evt->setEmitterID("Environment");
    evt->setType("GET_LIST");
    connector->broadcast(evt);
}

ArRef<Manager> Manager::getInstance()
{
  if(_uniqueInstance != Manager::nullRef())
    return _uniqueInstance;
  
  cerr << "Manager::getInstance() ERROR : you must create a manager first!" << endl;
  return Manager::nullRef();
}


void Manager::_onClose(const Renderer3D::CloseEvent & evt) {
    _environment->clearLocal();
}
